<template lang="pug">
view.date-time-picker(v-if="data.ready")
  picker(mode="multiSelector" :range="data.range" :value="data.value" @change="methods._commit" @columnchange="methods._column")
    slot
</template>
<script setup>
import {reactive, watch} from 'vue'
import {useDate} from '/common/script/date'

const emits = defineEmits(['update:value', 'change'])
const props = defineProps({
  start: String, // 开始时间，不设置则为当前时间 - props.dateRange * 86400000，是否减日期区间与exceededCurrentTime相关
  end: String, // 结束时间，不设置则为props.start + props.dateRange * 86400000
  value: String, // 默认时间
  format: {type: String, default: 'yyyy-mm-dd hh:ii'}, // 返回的日期时间格式
  exceededCurrentTime: {type: Boolean, default: false}, // 不能选择小于当前时间的日期时间
  dateRange: {type: [String, Number], default: 365}, // 开始和结束时间的日期区间
})

const data = reactive({
  range:[
    [], //year
    [], //month
    [], //day
    [], //hour
    [], //minute
  ],
  value: [0, 0, 0, 0, 0],
  ready: false, // 是否完成初始化
})

const pureData = {
  end: null, // 日期区间的结束日期
}

// 一次性监听，当minute有值，则说明数据初始化完成
const stop = watch(()=>data.range[4], ()=>{
  // 初始化默认值
  const {Y,m,d,H,i} = useDate(props.value)
  const {range, value} = data
  data.value = value.map((n,index)=>range[index].findIndex(v=>v==[Y+'年',m+'月',d+'日',H+'时',i+'分'][index]))
  // 完成初始化
  data.ready = true
  stop()
})

const methods = {
  _column(e){
    const {column, value} = e.detail
    data.value[column] = value
    const _method = ['Y', 'm', 'd', 'H', ''][column]
    if(_method) methods[`_${_method}`](value)
  },
  _commit(e){
    const format = props.format.replace(/[a-z]+/g, '|').split('|')
    const {range} = data
    const {value} = e.detail
    const datetime = value.map((n,i)=>range[i][n].replace(/[^\d]+/g, '')+format[i+1]).join('')
    emits('update:value', datetime)
    emits('change', datetime)
  },
  _Y(){// 选择年后，生成月
    const {code, today} = methods.isToday()
    const ms = Array(12).fill(0).map((n,i)=>(i+1).toString().padStart(2,'0')+'月')
    
    const b = ms.findIndex(m=>m==today.m)
    let e = ms.findIndex(m=>m==pureData.end.m+'月' )
    if(e < b) e = 11

    data.range[1] = code? ms.slice(b, e+1): ms

    data.value[1] = 0
    methods._m()
  },
  _m(){// 选择年月，生成日
    const {code, today} = methods.isToday('m')
    const {value: [Y, m], range: [Ys, ms]}= data
    // 下个月的第一天
    let nextMonth = useDate(useDate([Ys[Y].replace(/[^\d]+/g, ''), ms[m].replace(/[^\d]+/g, ''), '01'].join('-')).now + 31 * 86400000)
    let Ymd = [nextMonth.Y, nextMonth.m, '01'].join('-')
    // 这个月的最后一天
    let lastDay = useDate(useDate(Ymd).now - 86400000).d
    // 这个月的所有天数
    const ds = Array(Number(lastDay)).fill(0).map((n,i)=>(i+1).toString().padStart(2,'0')+'日')

    const b = ds.findIndex(d=>d==today.d)
    let e = ds.findIndex(d=>d==pureData.end.d+'日')
    if(e < b) e = ds.length - 1

    data.range[2] = code? ds.slice(b, e+1): ds
    data.value[2] = 0
    methods._d()
  },
  _d(){// 选择日后，生成时
    const {code, today} = methods.isToday('d')
    const Hs = Array(24).fill(0).map((n,i)=>i.toString().padStart(2,'0')+'时')
    data.range[3] = code? Hs.slice(Hs.findIndex(H=>H==today.H)): Hs
    data.value[3] = 0
    methods._H()
  },
  _H(){// 选择时后，生成分
    const {code, today} = methods.isToday('H')
    const is = Array(60).fill(0).map((n,i)=>i.toString().padStart(2,'0')+'分')
    data.range[4] = code? is.slice(is.findIndex(i=>i==today.i)): is
    data.value[4] = 0
  },
  /**
   * 当开启props.exceededCurrentTime时
   * 当前选择的日期是否是今天
   * @param key 颗粒度，可选Y,m,d,H
   * @return {code: 1, today: date} code==1为今天
   */
  isToday(key = 'Y'){
    const {exceededCurrentTime} = props
    const {value: [Y, m, d, H], range: [Ys, ms, ds, Hs]}= data
    let today = useDate()
    today = {Y: today.Y+'年', m: today.m+'月', d: today.d+'日', H: today.H+'时', i: today.i+'分'}
    let code = false
    if(exceededCurrentTime){
      code = today.Y == Ys[Y]
      switch(key){
        case 'H':
          code = code && today.H == Hs[H]
        case 'd':
          code = code && today.d == ds[d]
        case 'm':
          code = code && today.m == ms[m]
        break;
      }
    }
    return {code, today}
  },
  init(){
    const {dateRange, start, end, exceededCurrentTime} = props
    const today = useDate()
    const _start = useDate(start || today.nextDay(exceededCurrentTime? 0: dateRange*-1).YmdHi)
    const _end = useDate(end || today.nextDay(dateRange).YmdHi)
    pureData.end = _end
    const Y = Array(_end.Y - _start.Y + 1).fill(0).map((n,i)=>_start.Y/1 + i + '年')
    data.range[0] = Y
    methods._Y()
  }
}

methods.init()
</script>
<style lang="scss" scoped>
@use '/common/scss/mixin.scss' as *;

</style>